package manager

import (
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/model"
	"github.com/tianjigames/fairy/template"
	"github.com/tianjigames/fairy/util"
	"github.com/topfreegames/pitaya"
	"github.com/topfreegames/pitaya/logger"
	"math"
	"strconv"
	"sync"
)

var (
	LoadPlayerInfoManager *loadPlayerInfoManager
	loadPlayerInfoManagerOnce sync.Once
)

/**
加载玩家信息管理器
 */
type loadPlayerInfoManager struct {
	BaseManager
}

func NewLoadPlayerInfoManager() *loadPlayerInfoManager {
	loadPlayerInfoManagerOnce.Do(func() {
		LoadPlayerInfoManager = &loadPlayerInfoManager{}
	})
	return LoadPlayerInfoManager
}



/**
获取属性值
 */
func (p *loadPlayerInfoManager) GetAttrs(char model.CharObj,attributeList *model.AttributeList,attrFlag *constants.AttrFlag) int {
	if attrFlag == nil {
		return 0
	}

	nBaseAttr := 0
	nIdx := int(*attrFlag)
	if attributeList.MBaseAttrFlag.GetFlagByIndex(nIdx) {//属性值被修改过 需要重新计算
		if attributeList.AttrFactor == nil {
			attributeList.AttrFactor = pitaya.GetTemplateById(template.AttrFactorKey,
				strconv.FormatInt(int64(char.GetCareerId()*1000 + char.GetLv()),10)).(*template.AttrFactor)
		}

		nBaseAttr = p.CalBaseInfo(char,*attrFlag,attributeList.AttrFactor)
		attributeList.MBaseAttrs.SetAttr(nIdx,nBaseAttr)
		attributeList.MBaseAttrFlag.ClearFlagByIndex(nIdx)
	}else {
		nBaseAttr = attributeList.MBaseAttrs.GetAttr(nIdx)
	}

	//计算加成属性值
	nRefixAttr := p.GetRefixAttrByFlag(char,attributeList,attrFlag)
	nRefixAttr += p.refixAttrByFirst(attributeList,attrFlag)
	return nBaseAttr + nRefixAttr
}


/**
计算加成属性值
*/
func (p *loadPlayerInfoManager) GetRefixAttrByFlag(char model.CharObj,attributeList *model.AttributeList,attrFlag *constants.AttrFlag) int {
	if attrFlag == nil {
		return 0
	}

	nRefixAttr := 0
	nIdx := int(*attrFlag)
	if attributeList.MRefixAttrFlag.GetFlagByIndex(nIdx) {
		nRefixAttr = p.CalRefixAttr(char,attrFlag)
		attributeList.MRefixAttrs.SetAttr(nIdx,nRefixAttr)
		attributeList.MRefixAttrFlag.ClearFlagByIndex(nIdx)
	}else{
		nRefixAttr = attributeList.MRefixAttrs.GetAttr(nIdx)
	}

	return nRefixAttr
 }

/**
对有转换关系的属性进行修正
*/
func (p *loadPlayerInfoManager) refixAttrByFirst(attributeList *model.AttributeList,attrFlag *constants.AttrFlag) int {
	return 0
}

/**
计算玩家基本信息
*/
func (p *loadPlayerInfoManager) CalBaseInfo(obj model.CharObj,attrFlag constants.AttrFlag,
	attrFactor *template.AttrFactor) int {
	nRet := 0
	if obj == nil || attrFactor == nil {
		return 0
	}

	switch attrFlag {
	case constants.AttrStr: //力道
		_, ok := obj.(*model.PlayerObject)
		if !ok {
			_, ok = obj.(*model.RobotPlayer)
		}

		if ok {
			nRet = attrFactor.StrengPower
		}
	case constants.AttrSpi://元气
		_, ok := obj.(*model.PlayerObject)
		if !ok {
			_, ok = obj.(*model.RobotPlayer)
		}

		if ok {
			nRet = attrFactor.Spirit
		}
	case constants.AttrCon://体质
		_, ok := obj.(*model.PlayerObject)
		if !ok {
			_, ok = obj.(*model.RobotPlayer)
		}

		if ok {
			nRet = attrFactor.Constitution
		}
	case constants.AttrAgi://敏捷度
		_, ok := obj.(*model.PlayerObject)
		if !ok {
			_, ok = obj.(*model.RobotPlayer)
		}

		if ok {
			nRet = attrFactor.Agility
		}
	case constants.AttrMaxHp://体质值转为生命值 + 二级生命值
		nRet = CalCulateUtil.CalOriValue(attrFactor.Constitution,attrFactor.ConToHp,attrFactor.Health)
	case constants.AttrMaxMp://体质转为法力值 + 二级法力值
		nRet = CalCulateUtil.CalOriValue(attrFactor.Constitution,attrFactor.ConToMana,attrFactor.Mana);
	case constants.AttrAttackPhy://力道转为物理攻击值 + 二级物理攻击值
		nRet = CalCulateUtil.CalOriValue(attrFactor.StrengPower,attrFactor.StrToPattack,attrFactor.Pattack)
	case constants.AttrAttackMagic://元气值转为法术攻击值 + 二级法术攻击值
		nRet = CalCulateUtil.CalOriValue(attrFactor.Spirit,attrFactor.SpiToMattack,attrFactor.Mattack)
	case constants.AttrDefencePhy://力道转为物理防御值 + 基本物理防御值
		nRet = CalCulateUtil.CalOriValue(attrFactor.StrengPower,attrFactor.StrToPdefense,attrFactor.Pdefense)
	case constants.AttrDefenceMagic://元气转为法术防御值 + 基本法术防御值
		nRet = CalCulateUtil.CalOriValue(attrFactor.Spirit,attrFactor.SpiToMdefense,attrFactor.Mdefense)
	case constants.AttrHit://敏捷度转为攻击值 + 基本攻击值
		nRet = CalCulateUtil.CalOriValue(attrFactor.Agility,attrFactor.AgiToHit,attrFactor.Hit)
	case constants.AttrMiss://敏捷度转为闪避值 + 基本闪避追
		nRet = CalCulateUtil.CalOriValue(attrFactor.Agility,attrFactor.AgiToDodge,attrFactor.Miss)
	case constants.AttrCritical://暴击值
		nRet = attrFactor.Critical
	case constants.AttrCritResist://暴击抵抗值
		nRet = attrFactor.CritResist
	case constants.AttrCritIncreased://暴击加深值
		nRet = attrFactor.CritIncreased
	case constants.AttrCritReduction://暴击减免值
		nRet = attrFactor.CritReduction
	case constants.AttrThrough://穿透值
		nRet = attrFactor.Through
	case constants.AttrPatty://格挡值
		nRet = attrFactor.Patty
	case constants.AttrCriticalHit://会心一击
		nRet = attrFactor.CriticalHit
	case constants.AttrStrengthDefuse://御劲化解
		nRet = attrFactor.StrengthDefuse
	case constants.AttrDamageIncreased://伤害加深
		nRet = attrFactor.DamageIncrease
	case constants.AttrDamageReduction://伤害减免
		nRet = attrFactor.DamageReduce
	case constants.AttrExtraHit://额外伤害
		nRet = attrFactor.ExtraHit
	case constants.AttrExtraMiss://额外闪避值
		nRet = attrFactor.ExtraMiss
	case constants.AttrExtraCrtical://额外暴击值
		nRet = attrFactor.ExtraCritical
	case constants.AttrExtraCritResist://额外暴击减免值
		nRet = attrFactor.ExtraCritResist
	case constants.AttrExtraThrough://额外穿透值
		nRet = attrFactor.ExtraThrough
	case constants.AttrExtraPatty://额外格挡值
		nRet = attrFactor.ExtraPatty
	case constants.AttrAttackIce://冰攻击
		nRet = attrFactor.AttackIce
	case constants.AttrResistIce://抗冰
		nRet = attrFactor.ResistIce
	case constants.AttrReduceResistIce://冰抗值
		nRet = attrFactor.ReduceResistIce
	case constants.AttrAttackFire://火攻击
		nRet = attrFactor.AttackFire
	case constants.AttrResistFire://火抗
		nRet = attrFactor.ResistFire
	case constants.AttrReduceResistFire://火减抗
		nRet = attrFactor.ReduceResistFire
	case constants.AttrAttackThunder://雷攻击
		nRet = attrFactor.AttackThunder
	case constants.AttrResistThunder://雷抗
		nRet = attrFactor.ResistThunder
	case constants.AttrReduceResistThunder://雷减抗
		nRet = attrFactor.ReduceResistThunder
	case constants.AttrAttackPoison://毒攻击
		nRet = attrFactor.AttackPoison
	case constants.AttrResistPoison://毒抗
		nRet = attrFactor.ResistPosion
	case constants.AttrReduceResistPoison://毒减抗
		nRet = attrFactor.ReduceResistPosion
	case constants.AttrMoveSpeed:
		constantCfg := pitaya.GetTemplateById(template.ConstantKey,constants.PlayerDefaultSpeedId)
		if constantCfg != nil {
			nRet = constantCfg.(*template.Constant).Constant2
		}
	case constants.AttrAttackSpeed:
		nRet = attrFactor.AttackSpeed
	case constants.AttrHpRegeneRate:
		nRet = attrFactor.AutoRecoveryHealth
	case constants.AttrRage:
		nRet = 0
	case constants.AttrMpRegeneRate:
		nRet = attrFactor.AutoRecoveryMana
	}
	return nRet
}

/**
自己算修正属性值
 */
func (p *loadPlayerInfoManager) CalRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if nIdx == nil {
		return 0
	}

	if *nIdx == constants.AttrMoveSpeed && obj.IsFollow(){
		return 0
	}

	obj.SetCalRefixAttr(true)
	//卡牌影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetCardRefixAttr(obj,nIdx))
	//技能影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetSkillRefixAttr(obj,nIdx))
	//美人影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetBeautyRefixAttr(obj,nIdx))
	//宝石影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetGemRefixAttr(obj,nIdx))
	//仙剑影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetSwordRefixAttr(obj,nIdx))
	//元魂影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetSoulRefixAttr(obj,nIdx))
	//列命影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetLifeRefixAttr(obj,nIdx))
	//法宝影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetFabaoRefixAttr(obj,nIdx))
	//装备影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetEquipRefixAttr(obj,nIdx))
	//坐骑影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetRideRefixAttr(obj,nIdx))
	//翅膀影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetWingRefixAttr(obj,nIdx))
	//称号影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetTitleRefixAttr(obj,nIdx))
	//宝物影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetTreasureRefixAttr(obj,nIdx))
	//时装影响
	obj.SetTempCalRefixAttr(obj.GetTempCalRefixAttr() + p.GetFashionRefixAttr(obj,nIdx))

	obj.SetCalRefixAttr(false)
	nRet := obj.GetTempCalRefixAttr()
	obj.SetTempCalRefixAttr(0)
	return nRet
}

/**
获取卡牌影响的属性值
 */
func (p *loadPlayerInfoManager) GetCardRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	return 0
}

/**
被动技能对基本属性的影响值
 */
func (p *loadPlayerInfoManager) GetSkillRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	nRet := 0
	skills := obj.GetSkillData().SkillList
	var mPassiveSkill *template.SkillBase
	for i := 0;i<= obj.GetSkillData().GetSkillNum();i++ {
		v := pitaya.GetTemplateById(template.SkillBaseKey,strconv.FormatInt(int64(skills[i]),10))
		if v == nil {
			continue
		}

		mPassiveSkill = v.(*template.SkillBase)
		if mPassiveSkill.SkillClassify == constants.SkillTypePassive && mPassiveSkill.LogicId == SkillLogicAttackAttr {
			logic := SkillLogicManager.GetSkillLogic(mPassiveSkill.LogicId)
			if logic != nil {
				nRet += logic.GetAttr(obj,mPassiveSkill,nIdx)
			}
		}
	}

	return nRet
}

/**
美人对属性的影响值
 */
func (p *loadPlayerInfoManager) GetBeautyRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	return 0
}

/**
宝石对属性的影响值
*/
func (p *loadPlayerInfoManager) GetGemRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	player,ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.Bag == nil || player.Bag.GemItems == nil || len(player.Bag.GemItems) == 0 {
		return 0
	}

	nRet := 0
	for _,guid := range player.Bag.GemItems {
		gem := player.Bag.GetItemByGuid(guid)
		nRet += ItemManager.CalGemAttr(player,gem,nIdx)
	}
	return nRet
}

/**
仙剑对属性的影响值
*/
func (p *loadPlayerInfoManager) GetSwordRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	return 0
}

/**
元魂对属性的影响值
*/
func (p *loadPlayerInfoManager) GetSoulRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	return 0
}

/**
列命对属性的影响值
*/
func (p *loadPlayerInfoManager) GetLifeRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	return 0
}


/**
法宝对属性的影响值
*/
func (p *loadPlayerInfoManager) GetFabaoRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player,ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.MFabao == nil {
		return 0
	}

	//获取法宝自带属性加成值
	nRet := p.GetFabaoAddAttrValue(player,player.MFabao,nIdx)

	var mPassiveSkill *template.SkillBase
	var skillLogic SkillLogic
	for i := 0;i< len(player.MFabao.SkillList);i++ {//遍历技能列表 获取技能对属性的加成值
		tblID := player.MFabao.SkillList[i]
		if tblID <= 0 {
			continue
		}

		skillTbl := pitaya.GetTemplateById(template.FabaoSkillKey,strconv.FormatInt(int64(tblID),10))
		if skillTbl == nil {
			continue
		}

		v := pitaya.GetTemplateById(template.SkillBaseKey,strconv.FormatInt(int64(skillTbl.(*template.FabaoSkill).SkillBaseID),10))
		if v == nil {
			continue
		}

		mPassiveSkill = v.(*template.SkillBase)
		if mPassiveSkill.SkillClassify == constants.SkillTypePassive && mPassiveSkill.LogicId == SkillLogicAttackAttr {
			skillLogic = SkillLogicManager.GetSkillLogic(mPassiveSkill.LogicId)
			if skillLogic != nil {
				nRet += skillLogic.GetAttr(player,mPassiveSkill,nIdx)
			}
		}
	}
	return nRet
}

/**
获取法宝对某个属性的加成值
 */
func (p *loadPlayerInfoManager) GetFabaoAddAttrValue(player *model.PlayerObject,fabao *model.Fabao,attrId *constants.AttrFlag) int {
	if player == nil || fabao == nil || fabao.MFabaoBase == nil || attrId == nil {
		return 0
	}

	nRet := p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr1)
	if(player.IsPhysicAttack()){//物理攻击
		nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr2_0)
	}else { //法术攻击
		nRet += p.getFabaoAttrValueByAttrFlag(player, attrId, fabao.MFabaoBase.Attr2_1)
	}
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr3)
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr4)
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr5)
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr6)
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr7)
	nRet += p.getFabaoAttrValueByAttrFlag(player,attrId,fabao.MFabaoBase.Attr8)
	return nRet
}

/**
获取法宝的对某个属性的加成值
 */
func (p *loadPlayerInfoManager) getFabaoAttrValueByAttrFlag(player *model.PlayerObject,attrId *constants.AttrFlag,attr []int) int {
	if player == nil || attrId == nil || attr == nil || len(attr) < 2 {
		return 0
	}

	if attr[0] == int(*attrId) {
		return attr[1]
	}else{
		attrCFlag := constants.GetAttrFlagByValue(attr[0])
		rt := model.RefixTypeVTValue
		return 	p.CheckSpecialAttrByFlag(attrId,attrCFlag,&rt,attr[1],player.GetBaseAttr(attrId))
	}
}

/**
获取装备对属性的加成值
 */
func (p *loadPlayerInfoManager) GetEquipRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player,ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.Bag == nil || player.Bag.BodyEquips == nil || len(player.Bag.BodyEquips) == 0 {
		return 0
	}

	nRet := 0
	for _,guid := range player.Bag.BodyEquips {
		equip := player.Bag.GetItemByGuid(guid)
		nRet += ItemManager.CalEquipAttr(player,equip,nIdx)
	}

	return nRet
}

/**
获取坐骑对属性的加成值
 */
func (p *loadPlayerInfoManager) GetRideRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player,ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.RideList == nil {
		return 0
	}

	if *nIdx == constants.AttrMoveSpeed {
		curItem := player.RideList.GetRideData(player.RideList.MNRideIndex)
		if curItem == nil {
			return 0
		}

		return p.GetRideAddAttrValue(player,curItem,nIdx)
	}else{//其他属性 只要存在就会增加
		index := player.RideList.MNDefaultIndex
		nAttr := 0
		for i :=0;i<player.RideList.MNRideCount;i++ {
			ride := player.RideList.GetRideData(i)
			if ride == nil {
				continue
			}

			nAdd := p.GetRideAddAttrValue(player,ride,nIdx)
			if player.RideList.MNRideCount == 1 || index == i {
				nAttr += nAdd
			}else{
				nAttr += int(math.Floor(float64(nAdd)*0.3))
			}
		}

		return nAttr
	}
}

/**
获取翅膀对属性的加成值
 */
func (p *loadPlayerInfoManager) GetWingRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player, ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.WingList == nil {
		return 0
	}

	return p.GetWingAddAttrValue(player,player.WingList,nIdx)
}

/**
称号对玩家属性影响
 */
func (p *loadPlayerInfoManager) GetTitleRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player, ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.MTitleData == nil {
		return 0
	}

	return TitleManager.CalTitleAttr(player,nIdx)
}

/**
宝物对玩家属性影响
*/
func (p *loadPlayerInfoManager) GetTreasureRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player, ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.TreasureBag == nil || player.TreasureBag.BodyTreasures == nil || len(player.TreasureBag.BodyTreasures) == 0 {
		return 0
	}

	nRet := 0
	for _,guid := range player.TreasureBag.BodyTreasures {
		item,ok1 := player.TreasureBag.Treasures[guid]
		if !ok1 {
			continue
		}

		nRet += TreasureManager.CalTreasureAttr(player,item,nIdx)
	}

	return nRet
}

/**
时装影响玩家的加成属性值
 */
func (p *loadPlayerInfoManager) GetFashionRefixAttr(obj model.CharObj,nIdx *constants.AttrFlag) int {
	if obj == nil || nIdx == nil {
		return 0
	}

	player, ok := obj.(*model.PlayerObject)
	if !ok {
		return 0
	}

	if player.MFashionListData == nil {
		return 0
	}

	return FashionManger.CalFashionAttr(player,nIdx)
}

		/**
		获取翅膀属性加成值
		 */
func (p *loadPlayerInfoManager) GetWingAddAttrValue(player *model.PlayerObject,wingList *model.WingList,attrId *constants.AttrFlag) int {
	if player == nil || wingList == nil || attrId == nil {
		return 0
	}

	//没有开启翅膀
	if player.WingList.MNWingLevel <= 0 {
		return 0
	}

	v := pitaya.GetTemplateById(template.WingBaseKey,strconv.FormatInt(int64(player.WingList.MNWingLevel),10))
	if v == nil {
		return 0
	}
	wingTbl := v.(*template.WingBase)

	//特殊属性
	nRet := 0
	if player.IsPhysicAttack() {
		nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingTbl.PhyAttr1)
	}else{
		nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingTbl.MagAttr1)
	}

	nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingTbl.Attr2)
	nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingTbl.Attr3)
	nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingTbl.Attr4)

	//其他翅膀
	for i:=0;i<int(player.WingList.MNWingCount);i++ {
		v = pitaya.GetTemplateById(template.WingShowKey,strconv.FormatInt(int64(player.WingList.MWingData[i].TemplateId),10))
		if v == nil {
			continue
		}

		wingShowTbl := v.(*template.WingShow)
		nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingShowTbl.Attr1)
		nRet += p.GetWingAttrValueByAttrFlag(player,attrId,wingShowTbl.Attr2)
	}

	return nRet
}

/**
获取翅膀的某个加成属性数组加成值
 */
func (p *loadPlayerInfoManager) GetWingAttrValueByAttrFlag(player *model.PlayerObject,attrId *constants.AttrFlag, attr []int) int {
	if player == nil || attrId == nil || attr == nil || len(attr) < 2 {
		return 0
	}

	rt := model.RefixTypeVTValue
	if attr[0] == int(*attrId) {
		return p.GetAttrResult(&rt,attr[1],player.GetBaseAttr(attrId))
	}else{

		return p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(attr[0]),&rt,attr[1],player.GetBaseAttr(attrId))
	}
}

/**
获取坐骑对某个属性的加成值
 */
func (p *loadPlayerInfoManager) GetRideAddAttrValue(player *model.PlayerObject,ride *model.Ride,attrId *constants.AttrFlag) int {
	if ride == nil || ride.MRideBase == nil || attrId == nil {
		return 0
	}

	if *attrId == constants.AttrMoveSpeed {//移动速度
		if ride.MRideBase.SpeedRate <=0 {
			return 0
		}

		return int(float64(player.GetBaseSpeed())*float64(ride.MRideBase.SpeedRate)/100.0)
	}

	nRet := 0
	nBaseValue := player.GetBaseAttr(attrId)
	rt := model.RefixTypeVTValue

	//坐骑加成的公共属性
	commonItem1 := ride.MRideBase.CommonAttr1
	if commonItem1 != nil && len(commonItem1) >= 2 {
		if commonItem1[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,commonItem1[1],nBaseValue)
		}else {
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(commonItem1[0]),
				&rt,commonItem1[1],nBaseValue)
		}
	}

	commonItem2 := ride.MRideBase.CommonAttr2
	if commonItem2 != nil && len(commonItem2) >= 2 {
		if commonItem2[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,commonItem2[1],nBaseValue)
		}else {
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(commonItem2[0]),
				&rt,commonItem2[1],nBaseValue)
		}
	}

	commonItem3 := ride.MRideBase.CommonAttr3
	if commonItem3 != nil && len(commonItem3) >= 2 {
		if commonItem3[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,commonItem3[1],nBaseValue)
		}else {
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(commonItem3[0]),
				&rt,commonItem3[1],nBaseValue)
		}
	}

	commonItem4 := ride.MRideBase.CommonAttr4
	if commonItem4 != nil && len(commonItem4) >= 2 {
		if commonItem4[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,commonItem4[1],nBaseValue)
		}else {
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(commonItem4[0]),
				&rt,commonItem4[1],nBaseValue)
		}
	}

	//坐骑加成的特殊属性
	var careerAttr1 []int
	var careerAttr2 []int
	if player.IsPhysicAttack() {
		careerAttr1 = ride.MRideBase.SpecialPhyAttr1
		careerAttr2 = ride.MRideBase.SpecialPhyAttr2
	}else{
		careerAttr1 = ride.MRideBase.SpecialMagicAttr1
		careerAttr2 = ride.MRideBase.SpecialMagicAttr2
	}

	if careerAttr1 != nil && len(careerAttr1) >= 2 {
		if careerAttr1[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,careerAttr1[1],nBaseValue)
		}else{
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(careerAttr1[0]),
				&rt,careerAttr1[1],nBaseValue)
		}
	}

	if careerAttr2 != nil && len(careerAttr2) >= 2 {
		if careerAttr2[0] == int(*attrId) {
			nRet += p.GetAttrResult(&rt,careerAttr2[1],nBaseValue)
		}else{
			nRet += p.CheckSpecialAttrByFlag(attrId,constants.GetAttrFlagByValue(careerAttr2[0]),
				&rt,careerAttr2[1],nBaseValue)
		}
	}

	return nRet
}

/**
获取加成值
@param nAttrType 加成方式
@param nValue 加成值
@param baseValue 基本值
 */
func (p *loadPlayerInfoManager) GetAttrResult(nAttrType *model.RefixType,nValue,baseValue int) int {
	if nAttrType == nil || nValue < 0 {
		return 0
	}

	value := 0
	switch *nAttrType {
	case model.RefixTypeVTPercent:
		value = int(float32(nValue) / float32(100) * float32(baseValue))
	case model.RefixTypeVTValue:
		value = nValue
	}

	return value
}

/**
获取其他属性对主属性的加成值
 */
func (p *loadPlayerInfoManager) CheckSpecialAttrByFlag(attrMFlag,attrCFlag *constants.AttrFlag,
	vType *model.RefixType,vNum,nBaseValue int) int {
	if attrMFlag == nil || attrCFlag == nil || vType == nil {
		return 0
	}

	nValue := 0
	switch *attrMFlag {
	case constants.AttrAttackIce://冰攻击
	case constants.AttrAttackFire://火攻击
	case constants.AttrAttackThunder://雷攻击
	case constants.AttrAttackPoison://毒攻击
		if *attrCFlag == constants.AttrAttackAllelem { //对所有攻击类属性有加成效果
			nValue += p.GetAttrResult(vType, vNum, nBaseValue)
		}

	case constants.AttrResistIce://冰抗
	case constants.AttrResistFire://火抗
	case constants.AttrResistThunder://雷抗
	case constants.AttrResistPoison://毒抗
		if *attrCFlag == constants.AttrResistAllelem {
			nValue += p.GetAttrResult(vType,vNum,nBaseValue)
		}
	case constants.AttrReduceResistIce://冰减抗
	case constants.AttrReduceResistFire://火减抗
	case constants.AttrReduceResistThunder://类减抗
	case constants.AttrReduceResistPoison://毒减抗
		if *attrCFlag == constants.AttrReduceResistAllelem {
			nValue += p.GetAttrResult(vType,vNum,nBaseValue)
		}
	case constants.AttrAttackPhy://物攻
	case constants.AttrAttackMagic://法攻
		if *attrCFlag == constants.AttrAttackAll {//所有攻击类的属性有加成效果
			nValue += p.GetAttrResult(vType,vNum,nBaseValue)
		}
	case constants.AttrDefencePhy://物防
	case constants.AttrDefenceMagic://法防
		if *attrCFlag == constants.AttrDefenceAll {//所有防御类属性有加成效果
			nValue += p.GetAttrResult(vType,vNum,nBaseValue)
		}
	}

	return nValue
}

/**
重置某个基本属性值
 */
func (p *loadPlayerInfoManager) ResetBaseAttr(obj model.CharObj,attrId *constants.AttrFlag)  {
	obj.GetAttributeList().SetRefixAttrFlag(attrId,true)
	//某个属性改变 影响其他属性值发生改变
	p.SetAttrFlag(obj,attrId,true)
}

/**
某个属性值发生改变影响其他属性值
 */
func (p *loadPlayerInfoManager) SetAttrFlag(obj model.CharObj,attrId *constants.AttrFlag,bValue bool) bool {
	if obj == nil || attrId == nil {
		return false
	}

	if !CalCulateUtil.IsValidAttrId(int(*attrId)) {
		return false
	}

	attrList := obj.GetAttributeList()
	attrList.SetRefixAttrFlag(attrId,bValue)
	var at constants.AttrFlag
	switch *attrId {
	case constants.AttrStr://力道:物攻、物防
		at = constants.AttrAttackPhy
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrDefencePhy
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrSpi://元气：法功、法防
		at = constants.AttrAttackMagic
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrDefenceMagic
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrCon://体质：生命值、法力值
		at = constants.AttrMaxHp
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrMaxHp
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrAgi://敏捷度：命中、闪避值
		at = constants.AttrHit
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrMiss
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrAttackAllelem://所有攻击类属性
		at = constants.AttrAttackIce
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrAttackFire
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrAttackThunder
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrAttackPoison
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrResistAllelem://所有抗类属性
		at = constants.AttrResistIce
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrResistFire
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrResistThunder
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrResistPoison
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrReduceResistAllelem://所有减抗类属性
		at = constants.AttrReduceResistIce
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrReduceResistFire
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrReduceResistThunder
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrReduceResistPoison
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrAttackAll://攻击类：物攻、法功
		at = constants.AttrAttackPhy
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrAttackMagic
		attrList.SetRefixAttrFlag(&at,bValue)
	case constants.AttrDefenceAll://防御类：物攻、法功
		at = constants.AttrDefencePhy
		attrList.SetRefixAttrFlag(&at,bValue)
		at = constants.AttrDefenceMagic
		attrList.SetRefixAttrFlag(&at,bValue)
	}

	return true
}

/**
加载玩家数据
 */
func (p *loadPlayerInfoManager) LoadPlayerInfo(player *model.PlayerObject) (bool,error) {
	player.SetInit(true)
	defer func() {
		player.SetInit(false)
	}()

	//加载玩家背包数据
	b,err := p.loadPlayerBag(player)
	if err != nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerInfo failed,error:%s",err.Error())
		return false,err
	}
	if !b {
		return false,nil
	}

	//加载玩家宝物
	b,err = p.LoadPlayerTreasure(player)
	if err != nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerInfo failed,error:%s",err.Error())
		return false,err
	}
	if !b {
		return false,nil
	}

	b,err = p.LoadPlayerBaseInfo(player)
	if err != nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerInfo failed,error:%s",err.Error())
		return false,err
	}

	if !b {
		return false,nil
	}




	return false, err

}

/**
加载玩家背包数据
 */
func (p *loadPlayerInfoManager) loadPlayerBag(player *model.PlayerObject) (bool,error) {
	if player == nil || player.PlayerData == nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] loadPlayerBag playerObj is nil")
		return false,nil
	}

	b,err := ItemManager.LoadItemFromDB(player)
	if err != nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] loadPlayerBag failed,error:%s",err.Error())
		return false,err
	}

	return b,nil
}

/**
加载玩家宝物数据
 */
func (p *loadPlayerInfoManager) LoadPlayerTreasure(player *model.PlayerObject) (bool,error) {
	if player == nil {
		return false,nil
	}

	b,err := TreasureManager.loadTreasureItemFromDB(player)
	if err != nil {
		logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerTreasure failed,error:%s",err.Error())
		return false,err
	}

	return b,nil
}

/**
加载玩家基本信息
 */
func (p *loadPlayerInfoManager) LoadPlayerBaseInfo(player *model.PlayerObject) (bool,error) {
	if player == nil || player.PlayerData == nil {
		return false,nil
	}

	currTime := util.Now()
	pData := player.PlayerData
	pData.LoginTime = currTime
	gmAccountBaseInfo := GMAccountManager.GetGMAccountBase(pData.AccountName)
	if gmAccountBaseInfo != nil {
		player.GmAuthorityLevel = gmAccountBaseInfo.AuthorityLevel
	}

	if player.MBFirstLoginGame {
		pData.BagNum = constants.BagDefaultCellCount
		pData.StoreNum = constants.StoreDefaultCellCount
		//世界地图切换场景的等待时间
		pData.ChangeSceneTime = 0
		//聊天频道冷却时间
		pData.ChatTime = 0
		//全服邮件时间
		pData.ServerMailTime = currTime
		//初始化角色武器
		err := ItemManager.InitPlayerEquip(player)
		if err != nil {
			logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerBaseInfo failed,error:%s",err.Error())
			return false,err
		}

		//白名单账户
		if gmAccountBaseInfo != nil {
			err = FabaoManager.ActiveFabaoByGM(player)
			if err != nil {
				logger.Log.Errorf("[LoadPlayerInfoManager] LoadPlayerBaseInfo failed,error:%s",err.Error())
				return false,err
			}

			//给白名单账号装配物品
			//itemIdArray := gmAccountBaseInfo.IniItemID
			//itemCountArray := gmAccountBaseInfo.InitItemCout
			//if itemIdArray != nil && len(itemIdArray) > 0 {
			//	count := 1
			//	for _,id := range itemIdArray {
			//		if id <= 0 {
			//			continue
			//		}
			//
			//
			//	}
			//}
		}


	}

	return false, nil
}



























